View Javadoc
1   package org.apache.maven.surefire.testng;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.surefire.booter.Command;
23  import org.apache.maven.surefire.booter.CommandListener;
24  import org.apache.maven.surefire.booter.CommandReader;
25  import org.apache.maven.surefire.cli.CommandLineOption;
26  import org.apache.maven.surefire.providerapi.AbstractProvider;
27  import org.apache.maven.surefire.providerapi.ProviderParameters;
28  import org.apache.maven.surefire.report.ConsoleOutputReceiver;
29  import org.apache.maven.surefire.report.ReporterConfiguration;
30  import org.apache.maven.surefire.report.ReporterFactory;
31  import org.apache.maven.surefire.report.RunListener;
32  import org.apache.maven.surefire.suite.RunResult;
33  import org.apache.maven.surefire.testng.utils.FailFastEventsSingleton;
34  import org.apache.maven.surefire.testset.TestListResolver;
35  import org.apache.maven.surefire.testset.TestRequest;
36  import org.apache.maven.surefire.testset.TestSetFailedException;
37  import org.apache.maven.surefire.util.RunOrderCalculator;
38  import org.apache.maven.surefire.util.ScanResult;
39  import org.apache.maven.surefire.util.TestsToRun;
40  
41  import java.io.File;
42  import java.util.Collection;
43  import java.util.Collections;
44  import java.util.List;
45  import java.util.Map;
46  
47  import static org.apache.maven.surefire.booter.CommandReader.getReader;
48  import static org.apache.maven.surefire.report.ConsoleOutputCapture.startCapture;
49  import static org.apache.maven.surefire.testset.TestListResolver.getEmptyTestListResolver;
50  import static org.apache.maven.surefire.testset.TestListResolver.optionallyWildcardFilter;
51  import static org.apache.maven.surefire.util.TestsToRun.fromClass;
52  
53  /**
54   * @author Kristian Rosenvold
55   * @noinspection UnusedDeclaration
56   */
57  public class TestNGProvider
58      extends AbstractProvider
59  {
60      private final Map<String, String> providerProperties;
61  
62      private final ReporterConfiguration reporterConfiguration;
63  
64      private final ClassLoader testClassLoader;
65  
66      private final ScanResult scanResult;
67  
68      private final TestRequest testRequest;
69  
70      private final ProviderParameters providerParameters;
71  
72      private final RunOrderCalculator runOrderCalculator;
73  
74      private final List<CommandLineOption> mainCliOptions;
75  
76      private final CommandReader commandsReader;
77  
78      private TestsToRun testsToRun;
79  
80      public TestNGProvider( ProviderParameters bootParams )
81      {
82          // don't start a thread in CommandReader while we are in in-plugin process
83          commandsReader = bootParams.isInsideFork() ? getReader().setShutdown( bootParams.getShutdown() ) : null;
84          providerParameters = bootParams;
85          testClassLoader = bootParams.getTestClassLoader();
86          runOrderCalculator = bootParams.getRunOrderCalculator();
87          providerProperties = bootParams.getProviderProperties();
88          testRequest = bootParams.getTestRequest();
89          reporterConfiguration = bootParams.getReporterConfiguration();
90          scanResult = bootParams.getScanResult();
91          mainCliOptions = bootParams.getMainCliOptions();
92      }
93  
94      public RunResult invoke( Object forkTestSet )
95          throws TestSetFailedException
96      {
97          if ( isFailFast() && commandsReader != null )
98          {
99              registerPleaseStopListener();
100         }
101 
102         final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
103         final RunListener reporter = reporterFactory.createReporter();
104         /**
105          * {@link org.apache.maven.surefire.report.ConsoleOutputCapture#startCapture(ConsoleOutputReceiver)}
106          * called in prior to initializing variable {@link #testsToRun}
107          */
108         startCapture( (ConsoleOutputReceiver) reporter );
109 
110         RunResult runResult;
111         try
112         {
113             if ( isTestNGXmlTestSuite( testRequest ) )
114             {
115                 if ( commandsReader != null )
116                 {
117                     commandsReader.awaitStarted();
118                 }
119                 TestNGXmlTestSuite testNGXmlTestSuite = newXmlSuite();
120                 testNGXmlTestSuite.locateTestSets();
121                 testNGXmlTestSuite.execute( reporter );
122             }
123             else
124             {
125                 if ( testsToRun == null )
126                 {
127                     if ( forkTestSet instanceof TestsToRun )
128                     {
129                         testsToRun = (TestsToRun) forkTestSet;
130                     }
131                     else if ( forkTestSet instanceof Class )
132                     {
133                         testsToRun = fromClass( (Class<?>) forkTestSet );
134                     }
135                     else
136                     {
137                         testsToRun = scanClassPath();
138                     }
139                 }
140 
141                 if ( commandsReader != null )
142                 {
143                     registerShutdownListener( testsToRun );
144                     commandsReader.awaitStarted();
145                 }
146                 TestNGDirectoryTestSuite suite = newDirectorySuite();
147                 suite.execute( testsToRun, reporter );
148             }
149         }
150         finally
151         {
152             runResult = reporterFactory.close();
153         }
154         return runResult;
155     }
156 
157     boolean isTestNGXmlTestSuite( TestRequest testSuiteDefinition )
158     {
159         Collection<File> suiteXmlFiles = testSuiteDefinition.getSuiteXmlFiles();
160         return !suiteXmlFiles.isEmpty() && !hasSpecificTests();
161     }
162 
163     private boolean isFailFast()
164     {
165         return providerParameters.getSkipAfterFailureCount() > 0;
166     }
167 
168     private int getSkipAfterFailureCount()
169     {
170         return isFailFast() ? providerParameters.getSkipAfterFailureCount() : 0;
171     }
172 
173     private void registerShutdownListener( final TestsToRun testsToRun )
174     {
175         commandsReader.addShutdownListener( new CommandListener()
176         {
177             public void update( Command command )
178             {
179                 testsToRun.markTestSetFinished();
180             }
181         } );
182     }
183 
184     private void registerPleaseStopListener()
185     {
186         commandsReader.addSkipNextTestsListener( new CommandListener()
187         {
188             public void update( Command command )
189             {
190                 FailFastEventsSingleton.getInstance().setSkipOnNextTest();
191             }
192         } );
193     }
194 
195     private TestNGDirectoryTestSuite newDirectorySuite()
196     {
197         return new TestNGDirectoryTestSuite( testRequest.getTestSourceDirectory().toString(), providerProperties,
198                                              reporterConfiguration.getReportsDirectory(), getTestFilter(),
199                                              mainCliOptions, getSkipAfterFailureCount() );
200     }
201 
202     private TestNGXmlTestSuite newXmlSuite()
203     {
204         return new TestNGXmlTestSuite( testRequest.getSuiteXmlFiles(),
205                                        testRequest.getTestSourceDirectory().toString(),
206                                        providerProperties,
207                                        reporterConfiguration.getReportsDirectory(), getSkipAfterFailureCount() );
208     }
209 
210     public Iterable<Class<?>> getSuites()
211     {
212         if ( isTestNGXmlTestSuite( testRequest ) )
213         {
214             return Collections.emptySet();
215         }
216         else
217         {
218             testsToRun = scanClassPath();
219             return testsToRun;
220         }
221     }
222 
223     private TestsToRun scanClassPath()
224     {
225         final TestsToRun scanned = scanResult.applyFilter( null, testClassLoader );
226         return runOrderCalculator.orderTestClasses( scanned );
227     }
228 
229     private boolean hasSpecificTests()
230     {
231         TestListResolver specificTestPatterns = testRequest.getTestListResolver();
232         return !specificTestPatterns.isEmpty() && !specificTestPatterns.isWildcard();
233     }
234 
235     private TestListResolver getTestFilter()
236     {
237         TestListResolver filter = optionallyWildcardFilter( testRequest.getTestListResolver() );
238         return filter.isWildcard() ? getEmptyTestListResolver() : filter;
239     }
240 }